﻿using System;
using System.Collections.Generic;
using System.Text;

namespace TestKontrole2 {
    public class Populacija : ISkup {
        private string naziv;
        private int id;
        virtual public string Naziv {
            get { return naziv; }
            set { naziv = value; }
        }
        private int velicina;
        private string opisPopulacije;

        private Uvjet sjeme;
        private ElementRepository eleRep;

        virtual public string OpisPopulacije {
            get { return opisPopulacije; }
            set { opisPopulacije = value; }
        }

        virtual public int Id {
            get { return id; }
            set { id = value; }
        }

        virtual public Uvjet Sjeme {
            get { return sjeme; }
            set { sjeme = value; }
        }

        virtual public int Velicina {
            get { return velicina; }
            set { velicina = value; }
        }

        public Populacija(Uvjet uvjet) {
            Sjeme = uvjet;
            eleRep = ElementRepository.getInstanca(Sjeme);
            Velicina = eleRep.getBrojElemenataByUvjet(Sjeme);
        }

        public Populacija(Uvjet uvjet, string opis)
            : this(uvjet) {
            opisPopulacije = opis;
        }

        public Uvjet getUvjet() {
            return Sjeme;
        }

        public Uzorak createUzorak(int velicinaUzorka, int brojDodatnihStavki) {
            if (velicinaUzorka < Velicina) {
                Random random = new Random();
                eleRep.setUvjet(Sjeme);
                List<int> randomUzorakIndeksi = new List<int>(velicinaUzorka);
                List<IElement> elementi = new List<IElement>(velicinaUzorka);
                int i = 0;
                while (i < velicinaUzorka) {
                    int indeks = random.Next(Velicina);
                    if (!randomUzorakIndeksi.Contains(indeks)) {
                        elementi.Add(eleRep.getElementByRedniBroj(indeks));
                        randomUzorakIndeksi.Add(indeks);
                        i++;
                    }
                }
                List<int> randomDSIndeksi = new List<int>(brojDodatnihStavki);
                List<IElement> dodatneStavke = new List<IElement>();
                i = 0;
                while (i < brojDodatnihStavki) {
                    int indeks = random.Next(Velicina);
                    if (!randomUzorakIndeksi.Contains(indeks) &&
                        !randomDSIndeksi.Contains(indeks)) {
                        dodatneStavke.Add(eleRep.getElementByRedniBroj(indeks));
                        randomDSIndeksi.Add(indeks);
                        i++;
                    }
                }

                return new Uzorak(elementi, dodatneStavke);
            } else {
                throw new iznimke.VelicinaUzorkaNevazeca();
            }
        }

        /// <summary>
        /// prosirivanje basicUzorka tako da da se dodaju novi elementi dok ukupan broj elemenata u uzorku ne bude jednak zadanom
        /// </summary>
        /// <param name="noviBrojDS">novi broj dodatnih stavki</param>
        public Uzorak expandUzorak(Uzorak basicUzorak, int noviBrojElemenata, int noviBrojDS) {
            Random random = new Random();
            Uzorak uzorak = basicUzorak;
            int razlikaEle = noviBrojElemenata - basicUzorak.getVelicinaSkupa();
            if (razlikaEle > 0) {
                int i = 0;
                while (i < razlikaEle) {
                    int indeks = random.Next(Velicina);
                    IElement ele = eleRep.getElementByRedniBrojAndUvjet(indeks, Sjeme);
                    if (!basicUzorak.sadrziElement(ele.getID())) {
                        uzorak.addElement(ele);
                        i++;
                    }
                }
            }

            int razlikaDS = noviBrojDS - basicUzorak.getBrojDodatnihStavki();
            if (razlikaDS > 0) {
                int i = 0;
                while (i < razlikaDS) {
                    int indeks = random.Next(Velicina);
                    IElement ele = eleRep.getElementByRedniBrojAndUvjet(indeks, Sjeme);
                    if (!basicUzorak.sadrziElement(ele.getID())) {
                        uzorak.addDodatnaStavka(ele);
                        i++;
                    }
                }
            }
            return uzorak;
        }

        #region ISkup Members

        public string getID() {
            return naziv;
        }

        public int getVelicinaSkupa() {
            return Velicina;
        }

        #endregion


    }
}
